package com.example._03vehicle.base.interceptors;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class RateLimitInterceptor implements HandlerInterceptor {
    private static final int WINDOW_SIZE_SECONDS=60;
    private static final int MAX_REQUESTS_PER_WINDOW=3;
    private final ConcurrentHashMap<String, Integer> clientCounts = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, LocalDateTime> clientTimes = new ConcurrentHashMap<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取客户端请求后得到的IP
        String clientIp = request.getRemoteAddr();
        //获取当前时间
        LocalDateTime lastTime = clientTimes.get(clientIp);
        if (lastTime == null || LocalDateTime.now().isAfter(lastTime.plusSeconds(WINDOW_SIZE_SECONDS))) {
            //如果该客户端在当前窗口内没有请求过，则将其初始化为0，并更新时间
            clientCounts.put(clientIp, 1);
            clientTimes.put(clientIp, LocalDateTime.now());
            return true;
        }
        else {
            //如果该客户端在当前窗口内请求过，则将其计数加1，并更新时间
           Integer count = clientCounts.merge(clientIp,1,Integer::sum); //获取该客户端的请求次数
           // 如果请求次数超过限制，则拒绝访问，并返回错误响应
            if (count > MAX_REQUESTS_PER_WINDOW) {
               // response.setStatus(429);
                clientTimes.put(clientIp, LocalDateTime.now());
                throw new RuntimeException("Too many requests");

            }
            else {
                // 更新时间
                clientTimes.put(clientIp, LocalDateTime.now());
                return true;
            }
        }
    }
}
